using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;

namespace Nb.Common.Caching
{
    //todo...
    public class PerSessionCacheManager : IPerSessionCacheManager
    {        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="key">The key of the value to get.</param>
        /// <returns>The value associated with the specified key.</returns>
        public virtual T Get<T>(string key)
        {
            if (HttpContext.Current.Session == null)
            {
                return default(T);
            }

            object obj = HttpContext.Current.Session[key];
            if (obj == null)
            {
                return default(T);
            }
            T value = (T)obj;
            return value;
        }

        /// <summary>
        /// Adds the specified key and object to the cache.
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="data">Data</param>
        public virtual void Set(string key, object data)
        {
            if (HttpContext.Current.Session == null)
            {
                return;
            }

            HttpContext.Current.Session[key] = data;
        }

        /// <summary>
        /// Gets a value indicating whether the value associated with the specified key is cached
        /// </summary>
        /// <param name="key">key</param>
        /// <returns>Result</returns>
        public virtual bool IsSet(string key)
        {
            if (HttpContext.Current.Session == null)
            {
                return false;
            }

            object obj = HttpContext.Current.Session[key];
            if (obj == null)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Removes the value with the specified key from the cache
        /// </summary>
        /// <param name="key">/key</param>
        public virtual void Remove(string key)
        {
            if (HttpContext.Current.Session == null)
            {
                return;
            }

            HttpContext.Current.Session.Remove(key);
        }

        /// <summary>
        /// Removes items by pattern
        /// </summary>
        /// <param name="pattern">pattern</param>
        public virtual void RemoveByPattern(string pattern)
        {
            if (HttpContext.Current.Session == null)
            {
                return;
            }

            var enumerator = HttpContext.Current.Session.Keys.GetEnumerator();
            var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
            var keysToRemove = new List<string>();
            while (enumerator.MoveNext())
            {
                if (regex.IsMatch(enumerator.Current.ToString()))
                {
                    keysToRemove.Add(enumerator.Current.ToString());
                }
            }

            foreach (string key in keysToRemove)
            {
                HttpContext.Current.Session.Remove(key);
            }
        }

        /// <summary>
        /// Clear all cache data
        /// </summary>
        public virtual void Clear()
        {
            if (HttpContext.Current.Session == null)
            {
                return;
            }

            HttpContext.Current.Session.Clear();
        }
    }
}